﻿{
 extUtils
 --------
 Additional various routine which not yet available and/or not yet fixed on Lazarus v1.0.x
 
 This Unit is Part of GauExtUtils Package Component for Lazarus.
 Code name Package		: H-Băng
 Branch name Package	: Anh Giờ Đây
 Last Updated 			: 3:53 AM 16/12/2013 (GMT+07)

 Copyright (c) 2012 - 2013, Takeda Matsuki and others
 License : Modified LGPL (follow Lazarus license). 
}
 
unit extFileUtils;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, lazutf8classes, LazUTF8, LazUTF16
  {$IFDEF Windows} ,windows {$ENDIF};

// String control, since RAWByteString has better approach for Unicode then we would used it.
type
{$IF FPC_FULLVERSION >= 20700}
 StrCtrl = RawByteString;
{$ELSE}
 StrCtrl = WideString;
{$ENDIF}
  
{ flags for copy }
type
  TCopyFileFlagExt = (
    cffOverwriteFile,
    cffCreateDestDirectory,
    cffPreserveTime
    );
  TCopyFileFlagsExt = set of TCopyFileFlagExt;

{ TCopyDirTreeExt for extCopyDirTree function }
type
  TCopyDirTreeExt = class(TFileSearcher)
  private
    FSourceDir: StrCtrl;
    FTargetDir: StrCtrl;
    FFlags: TCopyFileFlagsExt;
    FCopyFailedCount:Integer;
  protected
    procedure DoFileFound; override;
    procedure DoDirectoryFound; override;
  end;


//------------------------------Some files routine-------------------------------------//

{$ifdef Windows}
function extWinToDosTime (Var Wtime : TFileTime;var DTime:longint):longbool;
Function extDosToWinTime (DosTime:longint;Var Wintime : TFileTime):longbool;
{$endif}

{--------------------------------------------------------------------------------------------
  Description : 
   @extIsDirectoryEmpty, would check if the directory is empty or not.
 --------------------------------------------------------------------------------------------}
function extIsDirectoryEmpty(const Directory : StrCtrl) : boolean;

{--------------------------------------------------------------------------------------------
  Description : 
   @CopyFile, this is new design of standard "fileutil.copyfile' which only available on 
    Lazarus v1.1 .
 --------------------------------------------------------------------------------------------}
function extCopyFile(const SrcFilename, DestFilename: StrCtrl;
                  Flags: TCopyFileFlagsExt=[cffOverwriteFile]): boolean;

{------------------------------------------------------------------------------------------------
  Description : 
   @CopyFile was taken from Lazarus v1.1 and bring it to be available on 
    current release (before Lazarus v1.1)
 ------------------------------------------------------------------------------------------------}				  
function extCopyFile(const SrcFilename, DestFilename: StrCtrl; PreserveTime: boolean): boolean;

{----------------------------------------------------------------------------------------------
  Description : 
   @extCopyDirTree has capability to "Copying directory with their child-directory tree 
    structure". This routine also has capability to setting their original (source) time-stamp.
 -----------------------------------------------------------------------------------------------}
function extCopyDirTree(const SourceDir, TargetDir: StrCtrl; Flags: TCopyFileFlagsExt=[]): Boolean;

{-------------------------------------------------------------------------------------------------
  Description : 
   @extFileSetDateUTF8 is similar with FileSetDateUTF8, but it has better unicode support 
    especially if you used Lazarus v1.0. For Lazarus > 1.0 already patched.
 --------------------------------------------------------------------------------------------------} 
function extFileSetDateUTF8(const FileName: StrCtrl; Age: Longint): Longint;

 
//------------------------------Some directories routine-------------------------------------//

{--------------------------------------------------------------------------------------------
  Description : 
   @DeleteDirectory has capability to "Delete directory with their child-directory tree 
    structure". This routine also has capability to Delete directory or files which has 
	read-only attribute.
 --------------------------------------------------------------------------------------------}
function extDeleteDirectory(const DirectoryName: StrCtrl; OnlyChildren, RemoveReadOnlyFiles : boolean): boolean;
 
{--------------------------------------------------------------------------------------------
  Description : 
   @extFileSearchUTF8 is similar like FileSearchUTF8. 
    But it's has better unicode support.
 --------------------------------------------------------------------------------------------}
function extFileSearchUTF8(const Name, DirList: StrCtrl; ImplicitCurrentDir : Boolean = True): StrCtrl;

{--------------------------------------------------------------------------------------------
  Description : 
   @extReadFileToStringUTF8 is similar like ReadFileToString. 
    But it's has unicode support.
 --------------------------------------------------------------------------------------------} 
function extReadFileToStringUTF8(const Filename: StrCtrl): StrCtrl;
 
{--------------------------------------------------------------------------------------------
  Description : 
   @extExtractFileDirUTF8 is similar like ExtractFileDir from RTL. 
    But it's has better unicode support.
 --------------------------------------------------------------------------------------------} 
function extExtractFileDirU(const FileName: StrCtrl): StrCtrl;

{--------------------------------------------------------------------------------------------
  Description : 
   @extExtractFilePathU is similar like ExtractFilePath from RTL. 
    But it's has better unicode support.
 --------------------------------------------------------------------------------------------} 
function extExtractFilePathU(const FileName: StrCtrl): StrCtrl;

{--------------------------------------------------------------------------------------------
  Description : 
   @extExtractFileExt is would return only file extension,
   e.g. ".exe" . It has better Unicode Support.
 --------------------------------------------------------------------------------------------}
function extExtractFileExt(const AFileName:StrCtrl):StrCtrl;

{--------------------------------------------------------------------------------------------
  Description : 
   @extExtractFileNameU is would return only file name but with extension of file type,
   e.g. "Windows.exe" . It has better Unicode Support.
 --------------------------------------------------------------------------------------------}
function extExtractFileNameU(const Filename: StrCtrl): StrCtrl;
  
{--------------------------------------------------------------------------------------------
  Description : 
   @extGetCurDirUTF8 is similar like GetCurrentDirUTF8. But it's has better unicode support.
 --------------------------------------------------------------------------------------------}  
function extGetCurDirUTF8 : StrCtrl;
 
{--------------------------------------------------------------------------------------------
  Description : 
   @extGetCurSelfFullNamePathUTF8 is similar with ParamStrUTF8(0), but it's has 
    better unicode support. Since fact, in random cases ParamStrUTF8(0) would 
	failed to work with Unicode.
 --------------------------------------------------------------------------------------------}
function extGetCurSelfFullNamePathU : StrCtrl;

{-------------------------------------------------------------
  Description : 
   @extStringReplaceU is similar with StringReplace, 
    but it's has better unicode support.
 -------------------------------------------------------------}
function extStringReplaceU(const S, OldPattern, NewPattern: StrCtrl;  Flags: TReplaceFlags): StrCtrl;

{-------------------------------------------------------------
  Description : 
   @extFileIsText is similar with FileIsText, but it's has 
    better unicode support.
 -------------------------------------------------------------}
function extFileIsText(const AFilename: StrCtrl): boolean; 

{-------------------------------------------------------------
  Description : 
   @extFileIsText is similar with FileIsText, but it's has 
    better unicode support.
 -------------------------------------------------------------}
function extFileIsText(const AFilename: StrCtrl; out FileReadable: boolean): boolean;

{-------------------------------------------------------------
  Description : 
   @extDirectoryIsWritable is similar with DirectoryIsWritable, 
    but it's has better unicode support.
 -------------------------------------------------------------}
function extDirectoryIsWritable(const DirectoryName: StrCtrl): boolean;

{-------------------------------------------------------------
  Description : 
   @extMultipleRenameFilesUTF8 is suitable to rename multiple
    Files.
 -------------------------------------------------------------}
function extMultipleRenameFilesUTF8(const NewName : StrCtrl; FilesList : TStrings):Boolean;

{-------------------------------------------------------------
  Description : 
   @extMultipleRenameDirUTF8 is suitable to rename multiple
    Directories.
 -------------------------------------------------------------}
function extMultipleRenameDirUTF8(const NewName : StrCtrl; DirList : TStrings):Boolean;

{-------------------------------------------------------------
  Description : 
   @extRenameDirUTF8 is Alternative -> for some unknown reason,
    FileUtil.RenameFileUTF8 was failed to be used for Rename
    the Directory.
 -------------------------------------------------------------}
function extRenameDirUTF8(const OldName, NewName:StrCtrl):Boolean;

{-------------------------------------------------------------
  Description : 
   @extIsFileExists is Alternative -> for some unknown reason,
    FileUtil.FileExistsUTF8 was failed to be used for check
    the file in the Directory.
 -------------------------------------------------------------}
function extIsFileExists (Const FileName : StrCtrl) : Boolean;

{---------------------------------------------------------------
  Description : 
   @DirectoryExists is Alternative -> for some unknown reason,
    FileUtil.DirectoryExistsUTF8 was failed to be used for check
    the Directory in cases directory contains Unicode Character.
 ---------------------------------------------------------------}
function extIsDirectoryExists (const Directory : StrCtrl) : Boolean;

function extFileAgeUTF8(const FileName: StrCtrl): Longint;

{$IFDEF Windows}

function IsValidPe(const FileName :StrCtrl) :Boolean;
function PeFileType(const FileName :StrCtrl):StrCtrl;

{$ENDIF}

implementation

{$I extFileUtils.inc}
{$IFDEF windows}
  {$i extWinFileUtils.inc}
{$ELSE}
  {$i extNixFileUtils.inc}
{$ENDIF}


initialization
  InitUtils;
  
end.
